/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package clases;

import java.io.File;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import javax.servlet.http.HttpServletRequest;
import org.apache.poi.hssf.usermodel.*;
//import org.apache.poi.hssf.usermodel.*;
import org.apache.struts.action.ActionMapping;

/**
 *
 * @author andreth
 */
public class Matriz extends Root implements Serializable, Reportable {

    private Integer idMatriz;
    private String nombre;
    private String fechacreacion;
    private String codigoUnidad;
    private String subm;
    private Integer numeroColumnas;
    private Integer numeroFilas;
    private ArrayList<Columna> columnas = new ArrayList<Columna>();
    private ArrayList<Celda> filas = new ArrayList<Celda>();
    private ArrayList<Categoria> categorias = new ArrayList<Categoria>();
    private Integer idReporte;
    private boolean plan =false;
    private boolean ajuste= false;
    private boolean ejec = false;
    private String tipo = "";
    private String ano = "";
    private String trimestre ="";
    private int[] tamanoCeldas;

    public String getAno() {
        return ano;
    }

    public void setAno(String ano) {
        this.ano = ano;
    }

    public String getTrimestre() {
        return trimestre;
    }

    public void setTrimestre(String trimestre) {
        this.trimestre = trimestre;
    }

    public String getTipo() {
        return tipo;
    }

    
    public void setTipo(String tipo) {
        this.tipo = tipo;
        if (tipo.equals("Planificacion")){
            this.plan = true;
        }
        else if (tipo.equals("Ajuste")){
            this.ajuste = true;
        }
        else if (tipo.equals("Ejecucion")){
            this.ejec = true;
        }
        else{
            System.out.println("ERROR en setTipo");
        }
    }
    
    public String getSubm() {
        return subm;
    }

    public void setSubm(String subm) {
        this.subm = subm;
    }
    public boolean isAjuste() {
        return ajuste;
    }

    public void setAjuste(boolean ajuste) {
        this.ajuste = ajuste;
    }

    public boolean isEjec() {
        return ejec;
    }

    public void setEjec(boolean ejec) {
        this.ejec = ejec;
    }

    public boolean isPlan() {
        return plan;
    }

    public void setPlan(boolean plan) {
        this.plan = plan;
    }

    public Integer getIdReporte() {
        return idReporte;
    }

    public void setIdReporte(Integer idReporte) {
        this.idReporte = idReporte;
    }

    public Integer getNumeroFilas() {
        return this.numeroFilas;
    }
    public void setNumeroColumnas(Integer numeroColumnas) {
       
        this.numeroColumnas = numeroColumnas;
      
        for (int i = 0; i < numeroColumnas; i++) {
            this.columnas.add(new Columna());
        }
        tamanoCeldas = new int[this.numeroColumnas];
    
    }
    public void setNumeroFilas(Integer numeroFilas) {
        this.numeroFilas = numeroFilas;
         
    }

    public Integer getNumeroColumnas() {
        return this.numeroColumnas;
    }

    public ArrayList<Categoria> getCategorias() {
        this.numeroFilas = this.categorias.size();
        return categorias;
    }

    public void setCategorias(ArrayList<Categoria> categorias) {
        this.categorias = categorias;
    }

    public Matriz() {
        this.fechacreacion = new GregorianCalendar().getTime().toString();
        System.out.print(fechacreacion);
    }

    public ArrayList<Columna> getColumnas() {
       
        if(columnas!=null){
             this.numeroColumnas = this.columnas.size();
            return columnas;
        }
        else{
            this.numeroColumnas=0;
            return new ArrayList<Columna>();
        }
    }

    public void setColumnas(ArrayList<Columna> columnas) {
        this.columnas = columnas;
    }

    public ArrayList<Celda> getFilas() {
        return filas;
    }

    public void setFilas(ArrayList<Celda> filas) {
        System.out.println("Matriz: setFilas");
        this.filas = filas;
    }

    public Matriz(Integer id, String nombre, String fechacreacion, String unidad) {
        this.idMatriz = id;
        this.nombre = nombre;
        this.fechacreacion = fechacreacion;
        this.codigoUnidad = unidad;

    }

    public String getFechacreacion() {
        return fechacreacion;
    }

    public void setFechacreacion(String fechacreacion) {
        this.fechacreacion = fechacreacion;
    }

    public Integer getIdMatriz() {
        return idMatriz;
    }

    public void setIdMatriz(Integer id) {
        this.idMatriz = id;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getCodigoUnidad() {
        return codigoUnidad;
    }

    public void setCodigoUnidad(String unidad) {
        this.codigoUnidad = unidad;
    }


    @Override
    public void reset(ActionMapping mapping, HttpServletRequest request) {
        this.columnas = new ArrayList<Columna>();
    }

    public Columna getColumna(int index) {
        while (this.columnas.size() <= index) {
            this.columnas.add(new Columna());
        }
        return this.columnas.get(index);
    }

    public Celda getFila(int index) {
        while (this.filas.size() <= index) {
            this.filas.add(new Celda());
        }
        return this.filas.get(index);
    }

    public Categoria getCategoria(int index) {
        while (this.categorias.size() <= index) {
            this.categorias.add(new Categoria());
        }
        return this.categorias.get(index);
    }

    public void agregarFila() {
        for (Columna columna : columnas) {
               this.filas.add(new Celda());
               this.numeroFilas++;
        }
    }
    
    /** Obtener todas las celdas ordenadas por la fila
     *  a la que corresponden
     * @return ArrayList<Fila> todas las filas de la matriz
     */
    public ArrayList<Fila> obtenerFilas(){
        ArrayList<Fila> filasOrdenadas = new ArrayList<Fila>();
        ArrayList<Celda> celdasFila = new ArrayList<Celda>();
        Fila fila = new Fila();
        for (int i=0 ; i<this.filas.size(); i++) {
            Celda celda = this.filas.get(i);
            int posicion = i % this.numeroColumnas;
            if (posicion == (this.numeroColumnas-1)){ // Se copmleto una fila
               celdasFila.add(celda);
               fila.setCeldas(celdasFila); 
               filasOrdenadas.add(fila);//Se guarda la fila actual
               celdasFila = new ArrayList<Celda>();
               fila = new Fila();
            }
            else{
                celdasFila.add(celda);
            }
         }
        return filasOrdenadas;
    }
    
        @Override
    public String toString(){
        String rep = "";
        rep += "Matriz(id,nombre) = "+"("+this.getIdMatriz()+","+this.getNombre()+")\n";
        rep += "Matriz Unidad y Creacion"+this.getCodigoUnidad()+"  "+ this.getFechacreacion()+"\n";
        rep += "Matriz Numfilas y NumColumnas = "
                + (this.getNumeroFilas()== null ? "Vacio" : this.numeroFilas )
                + (this.getNumeroColumnas()== null ? "Vacio" : this.numeroColumnas)+ "\n";
        rep += "Fin representacion de matriz";
        return rep;
    }

    @Override
    public void imprimirArchivoDoc(FileOutputStream f) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void imprimirArchivoTabla(FileOutputStream f) {
        System.out.println("ENTRANDO A IMPRIMIR TABLA");
             // Se crea el libro
            HSSFWorkbook libro = new HSSFWorkbook();

            // Se crea una hoja dentro del libro
            HSSFSheet hoja = libro.createSheet();
            
             int numf = hoja.getLastRowNum();
           
            //Aqui verificar si es una matriz, fila o reporte
            Matriz m = this;
           
            HSSFRow fila = hoja.createRow(numf);
            

            // Se crea una celda dentro de la fila
            HSSFCell celda = fila.createCell(0);

            // Se crea el contenido de la celda y se mete en ella.
            HSSFRichTextString texto = new HSSFRichTextString(m.getNombre());
            celda.setCellValue(texto);
           
                   this.crearMatriz(m,hoja);
                   numf = hoja.getLastRowNum();
                   hoja.createRow(++numf); // Una fila vacia
                
             
               
                numf++;
                fila = hoja.createRow(numf);
                celda = fila.createCell(0);

                // Se crea el contenido de la celda y se mete en ella.
                texto = new HSSFRichTextString("Fuente: "+m.getCodigoUnidad());
                celda.setCellValue(texto);
           
            
              
        try {
            libro.write(f);
            f.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
     
     }
    
     public void crearMatriz(Matriz m, HSSFSheet hoja) {
                ArrayList<Columna> columnas = m.getColumnas();
                int numfila = hoja.getLastRowNum();
                HSSFRow header = hoja.createRow(++numfila);
             
                System.out.println("Cantidad de columnas "+columnas.size());
               
                for (int i=0;i<columnas.size();i++) {
                     HSSFCell celda = header.createCell(i);
                     celda.setCellValue(columnas.get(i).getNombre()); 
                     System.out.println("Numero de fila: " +numfila);
                }
               
                ArrayList<Celda>filas = m.getFilas();
                System.out.println("Cantidad de filas "+filas.size());
                 String celdaFinal="";
                 String celDato="";
                 numfila++;
                 HSSFRow fila = hoja.createRow(numfila);
                 System.out.println("Numero de fila: " +numfila);
                for (int i=0;i<filas.size();i++){
                              
                    if (filas.get(i).getIdDato() == null){
                        HSSFCell celdaMat = fila.createCell((i)%columnas.size());
                        celdaMat.setCellValue(filas.get(i).getNombre());
                    }
                    else{
                       celDato = filas.get(i).getDato().getValor();
                       HSSFCell celdaMat = fila.createCell((i)%columnas.size());
                       celdaMat.setCellValue(celDato);
                    }
                      
                      System.out.println("CeldaDato "+celDato);
             
                      if (i > 0 && (i+1)%columnas.size() == 0){
                          System.out.println("CeldaFinal, iteracion "+ celdaFinal+" "+i);
                          numfila++;
                          fila = hoja.createRow(numfila);
                          
                      }
                }
}

    public int[] getTamanoCeldas() {
        return tamanoCeldas;
    }

    public void setTamanoCeldas(int tamano, int posicion) {
        
        if (this.tamanoCeldas!= null && this.tamanoCeldas[posicion] < tamano){
            System.out.println("Tamanocelda "+ this.tamanoCeldas[posicion]);
             this.tamanoCeldas[posicion] = tamano;
             System.out.println("Tamano y numero de columna"+ tamano+" "+posicion);
        }
    }
        
}
